import { convertAnnotatedSourceToFailureCase } from '@angular-eslint/test-utils';
import type {
  InvalidTestCase,
  ValidTestCase,
} from '@typescript-eslint/rule-tester';
import type { MessageIds, Options } from '../../../src/rules/pipe-prefix';

const messageIdPrefix: MessageIds = 'pipePrefix';
const messageIdSelectorAfterPrefix: MessageIds = 'selectorAfterPrefixFailure';

export const valid: readonly (string | ValidTestCase<Options>)[] = [
  {
    // should not fail when @Pipe not invoked
    code: `
        @Pipe
        class Test {}
      `,
    options: [{ prefixes: ['ng'] }],
  },
  {
    // should not fail when @Pipe does not have content
    code: `
        @Pipe({})
        class Test {}
      `,
    options: [{ prefixes: ['ng'] }],
  },
  {
    // should ignore the rule when the name is a variable
    code: `
        export function mockPipe(name: string): any {
          @Pipe({ name })
          class MockPipe implements PipeTransform {
            transform(input: any): any {
              return input;
            }
          }
          return MockPipe;
        }
      `,
    options: [{ prefixes: ['ng'] }],
  },
  {
    // should ignore the rule when the rule option is blank
    code: `
        @Pipe({
          name: 'ngBarFoo'
        })
        class Test {}
      `,
    options: [{ prefixes: [] }],
  },
  {
    // should succeed with prefix ng in @Pipe
    code: `
        @Pipe({
          name: 'ngBarFoo'
        })
        class Test {}
      `,
    options: [{ prefixes: ['ng'] }],
  },
  {
    // should succeed with multiple prefixes in @Pipe
    code: `
        @Pipe({
          name: 'ngBarFoo'
        })
        class Test {}
      `,
    options: [{ prefixes: ['ng', 'sg', 'mg'] }],
  },
  {
    // should succeed with multiple prefixes in @Pipe
    code: `
        @Pipe({
          name: \`ngBarFoo\`
        })
        class Test {}
      `,
    options: [{ prefixes: ['ng', 'sg', 'mg'] }],
  },
  {
    // should succeed when the class is not a Pipe
    code: `
        class Test {}
      `,
    options: [{ prefixes: ['ng'] }],
  },
  {
    // should do nothing if the name of the pipe is not a literal
    code: `
        const pipeName = 'fooBar';
        @Pipe({
          name: pipeName
        })
        class Test {}
      `,
    options: [{ prefixes: ['ng'] }],
  },
];

export const invalid: readonly InvalidTestCase<MessageIds, Options>[] = [
  convertAnnotatedSourceToFailureCase({
    description: 'should fail when Pipe has no "ng" prefix',
    annotatedSource: `
        @Pipe({
          name: 'foo-bar'
                ~~~~~~~~~
        })
        class Test {}
      `,
    messageId: messageIdPrefix,
    options: [{ prefixes: ['ng'] }],
    data: { prefixes: '"ng"' },
  }),
  convertAnnotatedSourceToFailureCase({
    description: 'should fail when Pipe has no selector after the prefix',
    annotatedSource: `
        @Pipe({
          name: 'ng'
                ~~~~
        })
        class Test {}
      `,
    messageId: messageIdSelectorAfterPrefix,
    options: [{ prefixes: ['ng'] }],
    data: { prefixes: '"ng"' },
  }),
  convertAnnotatedSourceToFailureCase({
    description:
      'should fail when Pipe has no prefix applying multiple prefixes',
    annotatedSource: `
        @Pipe({
          name: 'foo-bar'
                ~~~~~~~~~
        })
        class Test {}
      `,
    messageId: messageIdPrefix,
    options: [{ prefixes: ['ng', 'mg', 'sg'] }],
    data: { prefixes: '"ng", "mg" or "sg"' },
  }),
];
